﻿using Chart3D;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WSAP
{
    /// <summary>
    /// WNodeNet拓展方法
    /// </summary>
    public static class WNodeNetExtension
    {
        /// <summary>
        /// 获得节点响应
        /// </summary>
        /// <param name="node"></param>
        /// <param name="responseType"></param>
        /// <param name="dof"></param>
        /// <returns></returns>
        public static double GetResponse(this WNodeNet node, NodeResponseEnum responseType, int dof)
        {
            return Math.Round(node.GetResponse((int)responseType, dof), 4);
        }

        /// <summary>
        /// 获得节点响应
        /// </summary>
        /// <param name="node"></param>
        /// <param name="responseType"></param>
        /// <param name="dof"></param>
        /// <returns></returns>
        public static double GetDispResponse(this WNodeNet node, int dof)
        {
            return Math.Round(node.GetResponse(NodeResponseEnum.Disp, dof), 4);
        }

        /// <summary>
        /// 获得响应最大的节点
        /// </summary>
        /// <param name="node"></param>
        /// <param name="nodeJ"></param>
        /// <param name="responseType"></param>
        /// <param name="dof"></param>
        /// <returns></returns>
        public static WNodeNet GetMaxResponseNode(this WNodeNet node, WNodeNet nodeJ, NodeResponseEnum responseType, int dof)
        {
            if (node == null) return nodeJ;
            else if (Math.Abs(nodeJ.GetResponse(responseType, dof)) >
               Math.Abs(node.GetResponse(responseType, dof)))
                return nodeJ;
            else return node;
        }

        /// <summary>
        /// 获得最大响应的描述
        /// </summary>
        /// <param name="node"></param>
        /// <param name="responseType"></param>
        /// <param name="dof"></param>
        /// <returns></returns>
        public static string GetMaxResponseDescp(this WNodeNet node, NodeResponseEnum responseType, int dof)
        {
            return string.Format("最大{0}响应为:{1}\n节点编号:{2}\n节点坐标:{3},{4},{5}",
                WSAPHelper.GetResponseDescp(responseType),
                node.GetResponse(responseType, dof),
                node.GetTag(), Math.Round(node.GetX(), 2),
                Math.Round(node.GetY(), 2), Math.Round(node.GetZ(), 2));
        }

        /// <summary>
        /// 获得振型向量最大值
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static double GetMaxAbsEigenVertorValue(this WNodeNet node, int modeID)
        {
            var valueList = new List<double> { Math.Abs(node.GetEigenValue(modeID, 1)),
             Math.Abs(node.GetEigenValue(modeID, 2)),
             Math.Abs(node.GetEigenValue(modeID, 3))};
            return valueList.Max();
        }

        /// <summary>
        /// 获得数据点位置
        /// </summary>
        /// <param name="node"></param>
        /// <param name="isDeform"></param>
        /// <returns></returns>
        public static Point3D GetPoint3D(this WNodeNet node, bool isDeform, double factor)
        {
            return new Point3D((float)(isDeform ? node.GetX() + node.GetResponse(NodeResponseEnum.Disp, 1) * factor : node.GetX()),
                (float)(isDeform ? node.GetY() + node.GetResponse(NodeResponseEnum.Disp, 2) * factor : node.GetY()),
                (float)(isDeform ? node.GetZ() + node.GetResponse(NodeResponseEnum.Disp, 3) * factor : node.GetZ()));
        }

        /// <summary>
        /// 获得数据点位置
        /// </summary>
        /// <param name="node"></param>
        /// <param name="isDeform"></param>
        /// <returns></returns>
        public static Point3D GetPoint3D(this WNodeNet node, WSlabBuilderNet slab, SlabChartParam param)
        {
            return new Point3D((float)node.GetX(), (float)node.GetY(), 
                (float)(slab.GetValue(node, param) ));
        }

        /// <summary>
        /// 获得数据点位置
        /// </summary>
        /// <param name="node"></param>
        /// <param name="isDeform"></param>
        /// <returns></returns>
        public static Point3D GetPoint3D(this WNodeNet node, WNodeNet nodeJ, double lengthFactor, double factor)
        {
            //函数指针计算响应
            Func<int, int, double> getDisp = (dispIndex, rotationIndex) =>
            {
                return WSAPHelper.GetInterpolationPointsDisp(node.GetDispResponse(dispIndex), nodeJ.GetDispResponse(dispIndex),
                    node.GetDispResponse(rotationIndex), nodeJ.GetDispResponse(rotationIndex), lengthFactor);
            };
            //计算坐标
            var X = (nodeJ.GetX() - node.GetX()) * lengthFactor + node.GetX();
            var Y = (nodeJ.GetY() - node.GetY()) * lengthFactor + node.GetY();
            var Z = (nodeJ.GetZ() - node.GetZ()) * lengthFactor + node.GetZ();
            //计算位移响应
            var XResponse = getDisp(1, 5);
            var YResponse = getDisp(2, 4);
            var ZResponse = getDisp(3, 6);
            //返回数据点
            return new Point3D((float)(X + XResponse * factor),
               (float)(Y + YResponse * factor),
                 (float)(Z + ZResponse * factor));
        }

        /// <summary>
        /// 获得模态变形
        /// </summary>
        /// <param name="node"></param>
        /// <param name="modeID"></param>
        /// <returns></returns>
        public static Point3D GetPoint3D(this WNodeNet node, int modeID, double factor)
        {
            return new Point3D((float)(node.GetX() + node.GetEigenValue(modeID, 1) * factor),
                (float)(node.GetY() + node.GetEigenValue(modeID, 2) * factor),
                (float)(node.GetZ() + node.GetEigenValue(modeID, 3) * factor));
        }
    }
}
